import { tmpdir, homedir } from 'os'
import { join, resolve } from 'path'
import fs from 'fs'

/**
 * 返回指定的临时文件夹的路径
 * @example
 * C:\\Users\\sd401\\AppData\\Local\\Temp
 */
export const getOsTmpDir = (): string => tmpdir()

/**
 * 返回到当前用户的主目录的路径
 * @example
 * C:\\Users\\sd401
 */
export const getOsHomeDir = (): string => homedir()

/**
 * 执行node命令的目录.
 * @example
 * 如:
 * 在 E:\test\sub 目录下执行 `node hello.js` 那么 getProjectPath() 得到的值为: E:\test\sub
 * 在 E:\test 目录下执行 `node ./sub/hello.js` 那么 getProjectPath() 得到的值为: E:\test
 */
export const getProjectPath = (): string => resolve('./')

/**
 * 在指定目录创建临时文件夹
 * @example
 * // 在系统的临时目录下创建一个临时文件夹:
 * const userCreateTmpDir = await mkTmpDirAsync(getOsTmpDir())
 * @param baseDir 基础目录(临时文件夹会生成在该目录)
 * @param prefix 临时文件夹名称前缀
 * @return 临时文件夹路径
 */
export const mkTmpDirAsync = async (
  baseDir: string,
  prefix = 'tmp-'
): Promise<string> =>
  await fs.promises.mkdtemp(join(baseDir, prefix), { encoding: 'utf8' })

/**
 * 强制删除文件或文件夹(如果是文件夹且存在子孙目录或文件，会递归删除)
 * @example
 * // 在系统的临时目录下创建一个临时文件夹,然后删除
 * const userCreateTmpDir = await mkTmpDirAsync(getOsTmpDir())
 * await rmAsync(userCreateTmpDir)
 * @param dirPathOrFilePath 文件或文件夹路径
 */
export const rmAsync = async (dirPathOrFilePath: string): Promise<void> =>
  fs.promises.rm(dirPathOrFilePath, {
    recursive: true,
    force: true,
  })

/**
 * 在指定目录下创建文件夹。如果文件夹已存在，则不会执行任何操作
 * @example
 * // 在系统临时目录创建一个pan的文件夹
 * const panDirPath = await mkdirAsync(getOsTmpDir(),"pan")
 * // 在系统临时目录创建一个pan的文件夹，并在pan文件夹下创建xml文件夹
 * const panDirPath = await mkdirAsync(getOsTmpDir(),"pan/xml")
 * @param baseDir 文件夹会创建在该目录
 * @param dirName 文件夹名称
 * @return 文件夹路径(如果文件夹已存在则返回undefined)
 */

export const mkdirAsync = async (
  baseDir: string,
  dirName: string
): Promise<string> | undefined =>
  fs.promises.mkdir(join(baseDir, dirName), { recursive: true })
